<?php
/**
 *  💡 免责声明：本软件不得用于商业用途，仅做学习交流
 *  ⚠️ 权利声明：本软件由版权人提供产品技术支持
 *  📅 项目编号：NX2025-0135
 */
namespace App\Service\Im;

use App\Service\BaseService;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;

class ImService extends BaseService
{
    public function register($user_name, $web = 1, $CustomerService = 1): string
    {
        $token = bcrypt(rand(1000, 9999));
        $data = [
            'uid' => $user_name,
            'token' => $token,
            'device_flag' => $web,
            'device_level' => 0,
        ];
        $res = Http::asJson()->post($this->Url('/user/token'), $data)->collect();
        if ($res->get('status') == 200) {
            $this->extracted($CustomerService, $user_name);
            return $token;
        }
        return $token;
    }

    public function getCustomerService()
    {
        $uid = '';
        $flag = true;
        $cs = Cache::get('CustomerServiceIm') ?? collect();
        $cs = $cs->sort()->map(function ($item, $key) use (&$uid, &$flag) {
            if ($flag) {
                $uid = $key;
                $flag = false;
                ++$item;
            }
            return $item;
        });
        Cache::put('CustomerServiceIm', $cs);
        return $uid;
    }

    public function getUser()
    {
        $uid = '';
        $flag = true;
        $ui = Cache::get('UserIm') ?? collect();
        $ui = $ui->sort()->map(function ($item, $key) use (&$flag, &$uid) {
            if ($flag && $item == 0) {
                $uid = $key;
                $flag = false;
                $item = 1;
            }
            return $item;
        });
        Cache::put('UserIm', $ui);
        return $uid;
    }

    public function onlinestatus()
    {
        $online = Cache::get('ImOnline') ?? collect();
        $listc = Cache::get('CustomerServiceIm') ?? collect();
        $listu = Cache::get('UserIm') ?? collect();
        $data = $online->keys()->map(function ($item) {
            return (string) $item;
        })->toArray();
        $res = Http::asJson()->post($this->Url('/user/onlinestatus'), $data)->collect();

        if ($res->get('status') !== 400) {
            $res = $res->pluck('uid');
            if (filled($res)) {
                Cache::put('ImOnline', $online->only($res));
                Cache::put('CustomerServiceIm', $listc->only($res));
                Cache::put('UserIm', $listu->only($res));
            }
        }
    }

    public function sendAllMessage($message)
    {
        $online = Cache::get('ImOnline') ?? collect();
        $online = $online->keys()->map(function ($item) {
            return (string) $item;
        })->toArray();
        $data = [
            'header' => [
                'no_persist' => 0,
                'red_dot' => 1,
                'sync_once' => 0,
            ],
            'from_uid' => '系统管理员',
            'payload' => base64_encode(json_encode([
                'type' => 1,
                'content' => $message,
            ])),
            'subscribers' => $online,
        ];
        return Http::asJson()->post($this->Url('/message/sendbatch'), $data)->collect();
    }

    public function subscriberAdd($channel_id, array $uid)
    {
        $data = [
            'channel_id' => $channel_id,
            'channel_type' => 1,
            'reset' => 0,
            'subscribers' => $uid,
            'temp_subscriber' => 0,
        ];
        return Http::asJson()->post($this->Url('/channel/subscriber_add'), $data)->collect();
    }

    public function createChannel($channel_id, array $uid)
    {
        $data = [
            'channel_id' => $channel_id,
            'channel_type' => 2,
            'large' => 0,
            'ban' => 0,
            'subscribers' => $uid,
        ];
        return Http::asJson()->post($this->Url('/channel'), $data)->collect();
    }

    public function deleteChannel($channel_id, $channel_type, $uid)
    {
        $data = [
            'channel_id' => $channel_id,
            'channel_type' => $channel_type,
        ];
        $data2 = [
            'uid' => $channel_id,
            'channel_id' => $channel_id,
            'channel_type' => $channel_type,
        ];
        Http::asJson()->post($this->Url('/conversations/delete'), $data2)->collect();
        Http::asJson()->post($this->Url('/channel/delete'), $data)->collect();

        return true;
    }

    private function Url($path): string
    {
        return env('IM_LOCAL_URL') . $path;
    }

    /**
     * @param $CustomerService
     * @param $user_name
     */
    private function extracted($CustomerService, $user_name): void
    {
        if ($CustomerService == 1) {
            $list = Cache::get('CustomerServiceIm') ?? collect();
            $list->pull($user_name);
            Cache::put('CustomerServiceIm', $list->prepend(0, $user_name));
        } else {
            $list = Cache::get('UserIm') ?? collect();
            $list->pull($user_name);
            Cache::put('UserIm', $list->prepend(0, $user_name));
        }
        $list = Cache::get('ImOnline') ?? collect();
        $list = $list->put($user_name, now()->toDateTimeString());
        Cache::put('ImOnline', $list);
    }
}
